#include "displayer.hpp"
#include "config.hpp"
#include "display_str.hpp"
#include <iostream>
Color_t GetPlayerColor(char c)
{
    switch (c)
    {
    case 'A':
        return Color_Green;
    case 'Q':
        return Color_Red;
    case 'S':
        return Color_Blue;
    case 'J':
        return Color_Yellow;

    default:
        return Color_None;
    }
}
Displayer::Displayer(Game &g) : m_game(g)
{
}

Displayer::~Displayer(void)
{
}
void Displayer::Update(void)
{
    std::cout << "\033c";

    for (size_t i = 0; i < LAND_NUM; i++)
    {
        Land &land = m_game.m_land[i];
        int location = Location(i);
        switch (land.type)
        {
        case LandTypeStart:
            m_map[location].sign = 'S';
            m_map[location].color = Color_None;
            break;
        case LandTypeHospital:
            m_map[location].sign = 'H';
            m_map[location].color = Color_None;
            break;
        case LandTypeTool:
            m_map[location].sign = 'T';
            m_map[location].color = Color_None;
            break;
        case LandTypeGift:
            m_map[location].sign = 'G';
            m_map[location].color = Color_None;
            break;
        case LandTypePrison:
            m_map[location].sign = 'P';
            m_map[location].color = Color_None;
            break;
        case LandTypeMagic:
            m_map[location].sign = 'M';
            m_map[location].color = Color_None;
            break;
        case LandTypeMine:
            m_map[location].sign = '$';
            m_map[location].color = Color_None;
            break;
        case LandTypePark:
            m_map[location].sign = 'P';
            m_map[location].color = Color_None;
            break;
        case LandTypeEmpty1:
        case LandTypeEmpty2:
        case LandTypeEmpty3:
            switch (land.level)
            {
            case 0:
                m_map[location].sign = '0';
                break;
            case 1:
                m_map[location].sign = '1';
                break;
            case 2:
                m_map[location].sign = '2';
                break;
            case 3:
                m_map[location].sign = '3';
                break;
            default:
                break;
            }

            break;
        default:
            break;
        }
        if (land.barrier)
            m_map[location].sign = '#';
        m_map[location].color = GetPlayerColor(land.owner);
    }

    //user displayer
    for (size_t i = 0; i < m_game.m_user_num; ++i)
    {
        Actor &actor = m_game.m_actor[(m_game.m_current_user + i) % m_game.m_user_num];
        if (actor.m_bankruptcy || !actor.m_start)
            continue;
        int location = Location(actor.m_loc);
        m_map[location].color = GetPlayerColor(actor.m_name);
        m_map[location].sign = actor.m_name;
    }
    //display map
    for (int i = 0; i < 8; ++i)
    {
        for (int j = 0; j < 29; ++j)
        {
            print(m_map[i * 29 + j].sign, m_map[i * 29 + j].color);
        }
        print('\n', Color_None);
    }

    //display tips
    for (size_t i = 0; i < m_game.m_tip_queue.size(); ++i)
    {
        std::string s = m_game.m_tip_queue[(i + m_game.m_tip_idx) % m_game.m_tip_queue.size()];
        if (s.length() >= 1)
            std::cout << s << std::endl;
    }
    //display input tips
    std::cout << m_game.m_input_tip << std::endl;

    if (!m_game.m_gameover)
    {
        Actor &actor = m_game.m_actor[m_game.m_current_user];
        printstr(GetCName(actor.m_name), GetPlayerColor(actor.m_name));
    }
    std::cout << '>';
}

int Displayer::Location(int id)
{
    if (id < 28)
        return id;
    else if (id < 36)
        return (id - 28) * 29 + 28;
    else if (id < 64)
        return 202 + 64 - id;
    else if (id < 70)
        return (70 - id) * 29;
    else
    {
        return -1;
    }
}

void Displayer::print(char c, Color_t color)
{
    switch (color)
    {
    case Color_None:
        std::cout << c;
        break;
    case Color_Red:
        std::cout << "\033[31m" << c << "\033[0m";
        break;
    case Color_Green:
        std::cout << "\033[32m" << c << "\033[0m";
        break;
    case Color_Yellow:
        std::cout << "\033[33m" << c << "\033[0m";
        break;
    case Color_Blue:
        std::cout << "\033[34m" << c << "\033[0m";
        break;
    default:
        break;
    }
}

void Displayer::printstr(std::string s, Color_t color)
{
    switch (color)
    {
    case Color_None:
        std::cout << s;
        break;
    case Color_Red:
        std::cout << "\033[31m" << s << "\033[0m";
        break;
    case Color_Green:
        std::cout << "\033[32m" << s << "\033[0m";
        break;
    case Color_Yellow:
        std::cout << "\033[33m" << s << "\033[0m";
        break;
    case Color_Blue:
        std::cout << "\033[34m" << s << "\033[0m";
        break;
    default:
        break;
    }
}